﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace ZTD2PWV
{
    class Program
    {
        static void Main(string[] args)
        {
            string dirname = args[0];
            DirectoryInfo directoryInfo = new DirectoryInfo(dirname);
            foreach (FileInfo fileInfo in directoryInfo.GetFiles())
            {
                string filename = fileInfo.FullName;
                string fn = fileInfo.Name;
                string outfile = Path.Combine(dirname, fn.Replace(fileInfo.Extension, ".Arespwv"));
                ztd2pwv(filename, outfile);
            }
        }
        static void Maina(string[] args)
        {
            const int numfiles = 40000;
            string dirname = "E:\\data\\ztd\\";
            int start_doy = 250;
            int end_doy = 365;
            
            string [] ztdfiles=new string [numfiles];
            int numdir = getZTDByDoy(dirname, ref ztdfiles,start_doy,end_doy);
            //string ztdfile = "E:\\code\\gps_modis\\pppbak\\20152561240\\result\\20152561240.Aresztd";
            //FileStream fs = new FileStream(ztdfile, FileMode.Open);
            string[] staname = new string[30];
            string[] epochs = new string[numfiles];
            double[,] gpwv=new double[30,numfiles];
            double[,] gztd = new double[30,numfiles];
            getPWV(ztdfiles, ref staname,ref gztd, ref gpwv,ref epochs);
            outInfo(staname, epochs,gztd, gpwv);
            processZTD(ztdfiles, numdir);
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
        static bool processZTD(string[] ztdfiles,int ztd_num)
        {
            string ztdfile = "";
            string outfile = "";
            for (int i = 0; i < ztd_num;i++ )
            {
                ztdfile = ztdfiles[i];
                outfile = ztdfile + ".txt";
                ztd2pwv(ztdfile, outfile);

            }
                return true;
        }
        static int getZTDByDoy(string dirname,ref string [] ztdfiles ,int start_doy,int end_doy)
        {
            DirectoryInfo dirInfo = new DirectoryInfo(dirname);
            FileInfo [] files = dirInfo.GetFiles();
            int i = 0;
            foreach(FileInfo finfo in files)
            {
                string fn = finfo.Name;
                string strdoy = fn.Substring(4, 3);
                int tmpdoy = Convert.ToInt16(strdoy);
                if (finfo.Extension == ".txt") continue;
                if (tmpdoy >= start_doy && tmpdoy <= end_doy)
                {
                    ztdfiles[i] = finfo.FullName;
                    i++;
                }
//                Console.Write(finfo.FullName);
            }
            return i;
        }
        static void outInfo(string [] staname,string [] epochs,double [,] gztd,double[,] gpwv)
        {

//            for(int i=0;i<staname.Length;i++)
            for (int i = 0; i < 30; i++)
            {
                if (staname[i] == null) break;
                string fn = @"E:\\code\\gps_modis\\station\\"+staname[i]+".txt";
                StreamWriter sr = new StreamWriter(fn);
                string tmp = "SITE    ZTD    PWV";
                sr.WriteLine(tmp);
                for (int j = 0; j < epochs.Length; j++)
                {
                    if (epochs[j] == null) break;
                    string outline = staname[i] + "\t" + gztd[i, j].ToString("F9") + "\t" + gpwv[i, j].ToString("F9") + "\t" + epochs[j];
                    sr.WriteLine(outline);
                }
                sr.Close();
                Console.WriteLine(fn + "  has been saved!");
            }

        }
        static int getZTDfn(string topdir,ref string[] ztdfiles)
        {
            DirectoryInfo DirInfo = new DirectoryInfo(topdir);
            DirectoryInfo[] subdirs = DirInfo.GetDirectories();
            int countDir = 0;
            string fileid = "";
            string substr = "";
            if(subdirs != null)
                for(int i=0;i<subdirs.Length;i++)
                {
                    substr = subdirs[i].FullName;
                    int strlen = substr.Length;
                    fileid = substr.Substring(strlen - 11);
                    ztdfiles[i] = substr + "\\result\\" + fileid + ".Aresztd";
                    countDir++;
                }
            return countDir;
        }
        static int searchName(string[] snames,string sname,ref int arrLen)
        {
            for(int i = 0;i<snames.Length;i++)
            {
                if(snames[i] == null)
                { 
                    arrLen = i;
                    return -1;
                }
                if (sname == snames[i])
                    return i;
            }
            arrLen = snames.Length;
            return arrLen;
            
        }
        static void ztd2pwv(string  ztdfile,string pwvfile)
        {
            int i = 0;
            if (!File.Exists(ztdfile)) return;
            string myline = "";
            string outline = "SITE    LATITUDE           LONGITUDE    HEIGHT    ZTD(m)  PWV(mm)";
            StreamWriter sw = new StreamWriter(pwvfile);
            StreamReader sr = new StreamReader(ztdfile,Encoding.Default);
            myline = sr.ReadLine();
            sw.WriteLine(outline);
            while(!sr.EndOfStream)
            {
                myline = sr.ReadLine();
                string[] str = myline.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                double lon = Convert.ToDouble(str[4]) + Convert.ToDouble(str[5]) / 60.0 + Convert.ToDouble(str[6]) / 3600.0;
                double lat = Convert.ToDouble(str[1]) + Convert.ToDouble(str[2]) / 60.0 + Convert.ToDouble(str[3]) / 3600.0;
                double h = Convert.ToDouble(str[7]);
                double temp = 0;
                double pres = 0;
                double undn = 0;
                double doy = Convert.ToDouble(Path.GetFileName(ztdfile).Substring(4, 3));
                gtm.refGPT(doy, lat * Math.PI / 180.0, lon * Math.PI / 180.0, h, ref pres, ref temp, ref undn);
                double Tm = gtm.GetTm_GWMT3_C_D(doy, lat, lon, h);
                double II = gtm.II(Tm);
                double ZHD = gtm.ZHD(lat, h, pres);
                double tztd = Convert.ToDouble(str[8]);//mm
                double tpwv = (tztd * 1000 - ZHD) * II;
                outline = str[0] + "    " + lat.ToString() + "    " + lon.ToString() + "    " + h.ToString() + "    " + tztd.ToString() + "    " + tpwv.ToString();
                sw.WriteLine(outline);
            }
            sr.Close();
            sw.Close();
        }
        static void getPWV (string []ztdfiles,ref string []sname,ref double [,] gztd,ref double [,] gpwv,ref string [] epochs)
        {
            int j = 0;
            foreach (string ztdfile in ztdfiles)
            {
                if (!File.Exists(@ztdfile)) break;
                StreamReader sr = new StreamReader(ztdfile, Encoding.Default);
                string mline;
                mline = sr.ReadLine();
                int i = 0;
                //int j = 0;
                while ((mline = sr.ReadLine()) != null)
                {
                    //Console.WriteLine(mline.ToString());
                    string[] str = mline.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                    //gtm gtm1 = new gtm();
//                    sname[i] = str[0];
                    int arrLen = 0;
                    int idx = searchName(sname, str[0] ,ref arrLen);
                    if (idx < 0)
                        idx = arrLen;
                    sname[idx] = str[0];
                    double lon = Convert.ToDouble(str[4]) + Convert.ToDouble(str[5]) / 60.0 + Convert.ToDouble(str[6]) / 3600.0;
                    double lat = Convert.ToDouble(str[1]) + Convert.ToDouble(str[2]) / 60.0 + Convert.ToDouble(str[3]) / 3600.0;
                    double h = Convert.ToDouble(str[7]);
                    double temp = 0;
                    double pres = 0;
                    double undn = 0;
                    double doy = Convert.ToDouble(Path.GetFileName(ztdfile).Substring(4, 3));
                    gtm.refGPT(doy, lat * Math.PI / 180.0, lon * Math.PI / 180.0, h, ref pres, ref temp, ref undn);
                    double Tm = gtm.GetTm_GWMT3_C_D(doy, lat, lon, h);
                    double II = gtm.II(Tm);
                    double ZHD = gtm.ZHD(lat, h, pres);
                    double tztd = Convert.ToDouble(str[8]);//mm
                    double tpwv = (tztd * 1000 - ZHD) * II;
                    gztd[idx,j] = tztd;
                    gpwv[idx,j] = tpwv;
                    epochs[j] = Path.GetFileName(ztdfile).Substring(0,11);
                    string outstring = sname[idx] + "\t" + lon.ToString("F9") + "\t"
                        + lat.ToString("F9") + "\t" + tztd.ToString("F9") + "m\t" +
                        tpwv.ToString("F9") + "mm";
                    //Console.WriteLine(outstring);
                    //                Console.WriteLine(sname[i],lat.ToString(),lon.ToString,tpwv.ToString());
                    i++;
                    //j++;
                }

                sr.Close();
                j++;
            }
        }
    }
}

